import {
  Injectable,
  NotFoundException,
  Inject,
  forwardRef,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, IsNull } from 'typeorm';
import { Todo } from './entities/todo.entity';
import { CreateTodoDto } from './dto/create-todo.dto';
import { UpdateTodoDto } from './dto/update-todo.dto';
import { TodoReminderService } from './todo-reminder.service';

@Injectable()
export class TodoService {
  constructor(
    @InjectRepository(Todo)
    private readonly todoRepository: Repository<Todo>,
    @Inject(forwardRef(() => TodoReminderService))
    private readonly reminderService: TodoReminderService,
  ) {}

  async findAll(): Promise<Todo[]> {
    return await this.todoRepository.find({
      relations: [
        'creator',
        'assignee',
        'team',
        'children',
        'children.creator',
        'children.assignee',
        'children.team',
      ],
      where: {
        parentId: IsNull(),
      },
      order: { createdAt: 'DESC' },
    });
  }

  async findOne(id: number): Promise<Todo> {
    const todo = await this.todoRepository.findOne({
      where: { id },
      relations: ['creator', 'assignee', 'team', 'children', 'parent'],
    });
    if (!todo) {
      throw new NotFoundException(`Todo with ID ${id} not found`);
    }
    return todo;
  }

  async create(createTodoDto: CreateTodoDto): Promise<Todo> {
    console.log('TodoService.create 接收到的数据:', createTodoDto);
    const todo = this.todoRepository.create(createTodoDto);
    console.log('创建的 Todo 实体:', todo);
    const savedTodo = await this.todoRepository.save(todo);
    console.log('保存后的 Todo:', savedTodo);

    // 重新查询以获取关联的 creator、assignee 和 team 信息
    const todoWithRelations = await this.todoRepository.findOne({
      where: { id: savedTodo.id },
      relations: ['creator', 'assignee', 'team'],
    });

    return todoWithRelations || savedTodo;
  }

  async update(id: number, updateTodoDto: UpdateTodoDto): Promise<Todo> {
    const todo = await this.findOne(id);
    Object.assign(todo, updateTodoDto);
    const updatedTodo = await this.todoRepository.save(todo);

    // 如果更新了完成状态
    if (updateTodoDto.completed !== undefined) {
      // 如果任务被标记为完成，从提醒列表中移除
      if (updateTodoDto.completed === true) {
        this.reminderService.removeFromNotifiedList(id);
      }

      // 如果该任务有子任务，且被标记为完成，自动标记所有子任务为完成
      if (
        updateTodoDto.completed === true &&
        todo.children &&
        todo.children.length > 0
      ) {
        console.log(`父任务 ${id} 被标记为完成，自动标记所有子任务为完成`);
        await this.updateChildrenStatus(id, true);
      }

      // 如果该任务有父任务，检查是否需要更新父任务
      if (todo.parentId) {
        console.log(
          `子任务 ${id} 状态更新为: ${updateTodoDto.completed}，检查父任务 ${todo.parentId}`,
        );
        await this.checkAndUpdateParentStatus(todo.parentId);
      }
    }

    // 如果更新了到期时间，重置提醒状态
    if (updateTodoDto.dueDate !== undefined) {
      this.reminderService.resetNotification(id);
    }

    return updatedTodo;
  }

  async remove(id: number): Promise<void> {
    const todo = await this.findOne(id);
    const parentId = todo.parentId; // 保存父任务 ID

    await this.todoRepository.remove(todo);

    // 如果删除的是子任务，检查父任务状态
    if (parentId) {
      console.log(`删除子任务 ${id}，检查父任务 ${parentId} 状态`);
      await this.checkAndUpdateParentStatus(parentId);
    }
  }

  /**
   * 更新所有子任务的完成状态
   */
  private async updateChildrenStatus(
    parentId: number,
    completed: boolean,
  ): Promise<void> {
    const parent = await this.todoRepository.findOne({
      where: { id: parentId },
      relations: ['children'],
    });

    if (!parent || !parent.children || parent.children.length === 0) {
      return;
    }

    // 更新所有子任务
    for (const child of parent.children) {
      if (child.completed !== completed) {
        child.completed = completed;
        await this.todoRepository.save(child);

        // 如果子任务还有自己的子任务，递归更新
        const childWithChildren = await this.todoRepository.findOne({
          where: { id: child.id },
          relations: ['children'],
        });

        if (
          childWithChildren &&
          childWithChildren.children &&
          childWithChildren.children.length > 0
        ) {
          await this.updateChildrenStatus(child.id, completed);
        }
      }
    }
  }

  /**
   * 检查并更新父任务状态
   * - 当所有子任务完成时，自动标记父任务为已完成
   * - 当有子任务未完成时，自动取消父任务的完成状态
   */
  private async checkAndUpdateParentStatus(parentId: number): Promise<void> {
    const parent = await this.todoRepository.findOne({
      where: { id: parentId },
      relations: ['children'],
    });

    if (!parent) {
      console.log(`父任务 ${parentId} 不存在`);
      return;
    }

    // 如果没有子任务，不做任何操作
    if (!parent.children || parent.children.length === 0) {
      console.log(`父任务 ${parentId} 没有子任务`);
      return;
    }

    // 检查所有子任务是否都已完成
    const allChildrenCompleted = parent.children.every(
      (child) => child.completed,
    );

    const completedCount = parent.children.filter(
      (child) => child.completed,
    ).length;
    console.log(
      `父任务 ${parentId} 的子任务完成情况: ${completedCount}/${parent.children.length}`,
    );

    // 根据子任务状态更新父任务
    if (allChildrenCompleted && !parent.completed) {
      // 所有子任务都完成了，且父任务未完成，则标记父任务为完成
      console.log(`所有子任务已完成，自动标记父任务 ${parentId} 为完成`);
      parent.completed = true;
      await this.todoRepository.save(parent);

      // 递归检查父任务的父任务
      if (parent.parentId) {
        await this.checkAndUpdateParentStatus(parent.parentId);
      }
    } else if (!allChildrenCompleted && parent.completed) {
      // 有子任务未完成，但父任务已完成，则取消父任务的完成状态
      console.log(`有子任务未完成，自动取消父任务 ${parentId} 的完成状态`);
      parent.completed = false;
      await this.todoRepository.save(parent);

      // 递归检查父任务的父任务
      if (parent.parentId) {
        await this.checkAndUpdateParentStatus(parent.parentId);
      }
    }
  }
}
